package com.huxi.lang.validation.predicate;

import static com.huxi.lang.type.VTypeUtils.parseNumber;

import java.util.Date;

public abstract class Range<T> implements VPredicate {

	final RangeType mode;

	Range(RangeType mode) {
		this.mode = mode != null ? mode : RangeType.CLOSED_LOWER;
	}

	abstract protected Object min();

	abstract protected Object max();

	@Override
	public String toString() {
		return "Range";
	}

	public static class NumberRange extends Range<Number> {
		private Number min;
		private Number max;

		NumberRange(RangeType mode, Number min, Number max) {
			super(mode);
			this.min = min;
			this.max = max;
		}

		@Override
		protected Number min() {
			return min;
		}

		@Override
		protected Number max() {
			return max;
		}

		@Override
		public boolean test(Object t, boolean valueIfNull, boolean valueIfIllegalType) {
			if (t instanceof Number) {
				return mode.test((Number) t, min, max);
			}
			if (t instanceof CharSequence) {
				try {
					return mode.test(parseNumber(t.toString()), min, max);
				} catch (Exception e) {

				}
			}
			return t == null ? valueIfNull : valueIfIllegalType;
		}
	}

	public static class DateRange extends Range<Date> {
		private Date min;
		private Date max;

		DateRange(RangeType mode, Date min, Date max) {
			super(mode);
			this.min = min;
			this.max = max;
		}

		@Override
		protected Date min() {
			return min;
		}

		@Override
		protected Date max() {
			return max;
		}

		@Override
		public boolean test(Object t, boolean valueIfNull, boolean valueIfIllegalType) {
			if (t instanceof Date) {
				return mode.test((Date) t, min, max);
			}
			if (t instanceof CharSequence) {
				try {
					// return mode.test(parseNumber(t.toString()), min, max);
				} catch (Exception e) {

				}
			}
			return t == null ? valueIfNull : valueIfIllegalType;
		}
	}

	public static class StringRange extends Range<String> {
		private String min;
		private String max;

		StringRange(RangeType mode, String min, String max) {
			super(mode);
			this.min = min;
			this.max = max;
		}

		@Override
		protected String min() {
			return min;
		}

		@Override
		protected String max() {
			return max;
		}

		@Override
		public boolean test(Object t, boolean valueIfNull, boolean valueIfIllegalType) {
			if (t instanceof CharSequence) {
				return mode.test((String) t, min, max);
			}
			if (t instanceof CharSequence) {
				try {
					// return mode.test(parseNumber(t.toString()), min, max);
				} catch (Exception e) {

				}
			}
			return t == null ? valueIfNull : valueIfIllegalType;
		}
	}

}
